package com.nicedistractions.roadtriptracker;

import java.io.IOException;
import java.util.Date;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class TrackerService extends Service {
	
	protected static final String TAG = "Tracker";
	
	//How often to update the gps location
	protected static int TIME = 5000; //1800000 = Every 30 Minutes 
	protected static int DISTANCE = 1000; //Every 1000 Metres
	
	private LocationManager locationManager;
	private long lastUpload, lastUpdate = 0;
	private double latitude, longitude, altitude = 0;
	private float accuracy, bearing, speed = 0;
	private DBHelper db = new DBHelper(this);
	
	public static boolean running;	
	public static Date started, stopped;	
	
	@Override
    public int onStartCommand(Intent intent, int flags, int startId) {        
		Bundle extras = intent.getExtras();
		TIME = (intent.hasExtra("timeBetweenUpdates")) ? extras.getInt("timeBetweenUpdates") : 1800000; 
		DISTANCE = (intent.hasExtra("distanceBetweenUpdates")) ? extras.getInt("distanceBetweenUpdates") : 1000; 
		
		Log.i(TAG, "Time interval: " + TIME);
		Log.i(TAG, "Distance interval: " + DISTANCE);
        
		Notification note = new Notification(R.drawable.icon, "Tracker Running", System.currentTimeMillis());
		Intent i = new Intent(this, Control.class);

		i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);

		PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);

		note.setLatestEventInfo(this, "Road Trip Tracker", "Tracking....",	pi);
		note.flags |= Notification.FLAG_NO_CLEAR;

		startForeground(1337, note);
		
        return START_STICKY;        
    }

	/**
	 * Constructor
	 */
	public TrackerService() {
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.i(TAG, "onCreate");
		
		running = true;
		started = new Date();
		
		locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, TIME, DISTANCE, locationListener);	
	}
	
	/**
	 * Location receiver 
	 */
	LocationListener locationListener = new LocationListener() {
		/**
		 * When the location changes, it will be sent here.
		 */
	    public void onLocationChanged(Location location) {
	      // Called when a new location is found by the network location provider.
	      Log.i(TAG, "Acc: " + location.getAccuracy());
	      Log.i(TAG, "Lat: " + location.getLatitude() + " - Long: " + location.getLongitude());
	      
	      latitude = location.getLatitude();
	      longitude = location.getLongitude();
	      accuracy = location.getAccuracy();
	      altitude = location.getAltitude();
	      bearing = location.getBearing();
	      speed = location.getSpeed();
	      lastUpdate = location.getTime();
	      
	      //Update the app GUI
	      updateControl();	      
	      
	      //Save the location to the database & attempt an upload
	      db.open();
	      long locationId = db.addLocation(latitude, longitude, accuracy, altitude, bearing, speed, lastUpdate); 
	      
	      //Attempt to upload
	      try {
			Uploader.postToTracker(locationId, latitude, longitude, accuracy, altitude, bearing, speed, lastUpdate, db);	
			Uploader.uploadAll(db);
		} catch (ClientProtocolException e) {
			Log.e(TAG, "HTTP Error");
			e.printStackTrace();
		} catch (IOException e) {
			Log.e(TAG, "Server Error");
			e.printStackTrace();
		} catch (JSONException e) {
			Log.e(TAG, "JSON Error");
			e.printStackTrace();
		}
	      db.close();   
	    }

	    public void onStatusChanged(String provider, int status, Bundle extras) {
	    	Log.i(TAG, "Status change: " + status);
	    }

	    public void onProviderEnabled(String provider) {
	    	Log.i(TAG, "GPS ON");
	    }

	    public void onProviderDisabled(String provider) {
	    	Log.i(TAG, "GPS OFF");
	    }
	  };
	  
	  @Override
	  public void onDestroy() {
		  super.onDestroy();
		  
		  running = false;
		  stopped = new Date();
		  
		  updateControl();
		  
		  locationManager.removeUpdates(locationListener);
	  }
	  
	  /**
	   * Sends updates back to the Control activity.
	   */
	  private void updateControl() {
		  Control.updateValues(lastUpload, lastUpdate, latitude, longitude, accuracy, bearing, speed, altitude);
//		  Tools.writeLocation(latitude, longitude, this);
	  }

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
}